package com.tarena.luban.test.service;

import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import com.sun.corba.se.spi.orbutil.threadpool.Work;
import com.tarena.luban.test.bo.*;
import com.tarena.luban.test.repository.WorkerAreaRepository;
import com.tarena.luban.test.repository.WorkerCategoryRepository;
import com.tarena.luban.test.repository.WorkerRepository;
import com.tarena.passport.protocol.LoginUser;
import com.tarena.passport.sdk.context.SecurityContext;
import com.tarena.tp.attach.server.client.AttachApi;
import com.tarena.tp.attach.server.dto.AttachDTO;
import com.tarena.tp.attach.server.param.AttachUpdateParam;
import com.tarena.tp.attach.server.query.AttachQuery;
import com.tarena.tp.luban.account.server.client.AccountApi;
import com.tarena.tp.luban.account.server.dto.AccountDTO;
import com.tarena.tp.luban.worker.server.common.enums.AuditStatusEnum;
import com.tarena.tp.luban.worker.server.dto.WorkerDTO;
import com.tarena.tp.luban.worker.server.dto.param.IdCardParam;
import com.tarena.tp.luban.worker.server.dto.param.WorkerCreateParam;
import com.tedu.inn.protocol.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class WorkerService {
    //针对师傅业务 准备3个仓储层 workerRepo workerAreaRepo workerCatRepo
    public Long create(WorkerCreateParam workerCreateParam) throws BusinessException {
        //1. 新增师傅,绑定userId,获取userId
        Long userId=getUserIdFromJwt();
        workerCreateParam.setUserId(userId);
        //2. 校验idCard phone 应该
        checkPhoneAndIdCard(workerCreateParam);
        //3. 新增worker
        Long workerId=saveWorker(workerCreateParam);
        //4. 新增worker_area
        saveWorkerArea(workerCreateParam);
        //5. 新增worker_category
        saveWorkerCategory(workerCreateParam);
        //6. 返回workerId
        return workerId;
    }
    @Autowired
    private WorkerCategoryRepository workerCategoryRepository;

    private void saveWorkerCategory(WorkerCreateParam workerCreateParam) {
        //删除
        workerCategoryRepository.deleteCategories(workerCreateParam.getUserId());
        //新增
        workerCategoryRepository.saveCategories(workerCreateParam);
    }
    @Autowired
    private WorkerAreaRepository workerAreaRepository;
    // 新增worker是幂等 这里也保持幂等,只保证最后一次的新增
    private void saveWorkerArea(WorkerCreateParam workerCreateParam) {
        //删除 delete from worker_area where user_id=#{userId}
        workerAreaRepository.deleteAreas(workerCreateParam.getUserId());
        //新增
        workerAreaRepository.saveAreas(workerCreateParam);
    }

    /**
     * @param workerCreateParam 一个userId申请入驻的师傅 在驳回申请后,可以重新填写申请重新入驻
     * 同一个登录用户不止一次调用,需要设计成幂等.最后 无论入驻多少次,只保存最后一次注入数据.
     * @return
     */
    @Autowired(required = false)
    private AttachApi attachApi;
    @Autowired
    private WorkerRepository workerRepository;
    private Long saveWorker(WorkerCreateParam workerCreateParam) {
        //保证幂等,先使用userId删除 当前系统的已存在的worker数据.
        workerRepository.deleteWorker(workerCreateParam.getUserId());
        //使用请求参数 写入师傅数据
        Long workerId=workerRepository.saveWorker(workerCreateParam);
        //新增完师傅 使用业务id值 绑定图片
        List<AttachUpdateParam> updateParams=new ArrayList<>();
        //上传师傅入驻,提交了几张图片信息,最重要封装的updateParams就有几个元素
        //是否是封面 bizType=100 bizId=userId id=图片id
        List<IdCardParam> attachList = workerCreateParam.getAttachList();
        for (IdCardParam idCardParam : attachList) {
            AttachUpdateParam attachUpdateParam=new AttachUpdateParam();
            attachUpdateParam.setIsCover(1);
            attachUpdateParam.setBusinessType(100);
            attachUpdateParam.setBusinessId(workerCreateParam.getUserId().intValue());
            attachUpdateParam.setId(idCardParam.getId());
            updateParams.add(attachUpdateParam);
        }
        //保证幂等 删除当前bizType+bizId曾经绑定过的图片.
        AttachUpdateParam deleteParam=new AttachUpdateParam();
        deleteParam.setBusinessType(100);
        deleteParam.setBusinessId(workerCreateParam.getUserId().intValue());
        attachApi.deleteAttachByBusinessIdAndBusinessType(deleteParam);
        int result = attachApi.batchUpdateAttachByIdList(updateParams);
        return workerId;
    }

    private void checkPhoneAndIdCard(WorkerCreateParam workerCreateParam) {
        //不做,为测试打开,不处理
        log.info("身份证,和手机号 测试通过");
    }

    private Long getUserIdFromJwt() throws BusinessException {
        //无法获取真正的登录userId
        LoginUser loginToken = SecurityContext.getLoginToken();
        //判断是否为空
        if (loginToken==null || loginToken.getUserId()==null){
            //抛自定义异常
            throw new BusinessException("-999","user没登录");
        }
        return loginToken.getUserId();
    }

    /**
     * 查询当前登录用户 对应的师傅数据
     * @return
     */
    @Autowired(required = false)
    private AccountApi accountApi;
    public WorkerBO detail() throws BusinessException {
        //1. 获取动态登录的userId
        Long userId = getUserIdFromJwt();
        //2. 利用userId查询worker数据--workerRepository
        WorkerBO workerBO=workerRepository.findWorker(userId);
        //3. 判断是否查询的师傅数据为空 workerBO==null workerBO.getId()==null
        if (workerBO==null||workerBO.getId()==null){
            //3.1 是空 表示当前登录的用户没有入驻师傅,返回一个 审核状态为3 accountBO 中总金额为0的worker
            workerBO=new WorkerBO();
            //审核状态
            workerBO.setAuditStatus(3);
            //accountBO
            AccountBO accountBO=new AccountBO();
            accountBO.setTotalAmount(0L);
            workerBO.setAccountBO(accountBO);
        }else {
            //3.2 不为空 当前用户入驻过 审核状态 未审核2 已通过1 驳回0
            //封装areaBO--is他<Work二Are啊BO>ory userId
            List<WorkerAreaBO> areas=workerAreaRepository.findAreas(userId);
            workerBO.setWorkerAreaBOList(areas);
            //封装categoryBO--workerCategoryRepository userId
            List<WorkerCategoryBO> categories=workerCategoryRepository.findCategories(userId);
            workerBO.setWorkerCategoryBOList(categories);
            //远程调用attachApi 读取图片数据 封装AttachInfoBO bizType=100L bizId=userId TODO
            List<AttachInfoBO> attaches=getWorkerAttach(100,userId);
            workerBO.setAttachInfoBOList(attaches);
            //远程调用
            AccountDTO accountDTO = accountApi.getAccountByUserId(userId);
            AccountBO accountBO=new AccountBO();
            accountBO.setTotalAmount(accountDTO.getTotalAmount());
            workerBO.setAccountBO(accountBO);
            //如果师傅的审核状态是0 表示本次申请被驳回,我可以创建AuditRepository查询worker_audit_log日志
            //获取驳回的具体原因 reject_reason
            if (workerBO.getAuditStatus()==0){
                //UNDO 查询auditLog表格
                workerBO.setRejectReason("资质不全");
            }
        }
        return workerBO;
    }

    private List<AttachInfoBO> getWorkerAttach(int businessType, Long businessId) {
        //1.需要attachApi的查询方法 提供一个查询参数
        AttachQuery attachQuery=new AttachQuery();
        attachQuery.setBusinessId(businessId.intValue());
        attachQuery.setBusinessType(businessType);
        //2. 拿到查询结果 进行进一步的解析封装
        List<AttachDTO> attachDTOS = attachApi.getAttachInfoByParam(attachQuery);
        List<AttachInfoBO> attaches=new ArrayList<>();
        //3.如果查询结果不为空,需要封装一个List<AttachInfoBO>对象
        if (CollectionUtils.isNotEmpty(attachDTOS)){
            //worker有绑定的图片数据
            //当前图片 url地址 保证能够访问到图片的 url前缀 http://localhost:8092/static/图片名称.jpg
            //从DTO对象中拿到fileUuid拼接url前缀
            String urlPrefix="http://localhost:8092/static/";
            for (AttachDTO attachDTO : attachDTOS) {
                String url=urlPrefix+attachDTO.getFileUuid();
                log.info("当前师傅:{},有一张图片:{}",businessId,url);
                AttachInfoBO attachInfoBO=new AttachInfoBO();
                attachInfoBO.setUrl(url);
                attaches.add(attachInfoBO);
            }
        }
        return attaches;
    }

    public WorkerDTO queryWorkerByUserId(Long userId) {
        List<WorkerAreaBO> areas = workerAreaRepository.findAreas(userId);
        List<WorkerCategoryBO> categories = workerCategoryRepository.findCategories(userId);
        WorkerDTO workerDTO=new WorkerDTO();
        List<Integer> areaIds=new ArrayList<>();
        List<Integer> categoryIds=new ArrayList<>();
        if (CollectionUtils.isNotEmpty(areas)){
            for (WorkerAreaBO area : areas) {
                Long areaId=area.getAreaId();
                areaIds.add(areaId.intValue());
            }
        }
        if (CollectionUtils.isNotEmpty(categoryIds)){
            for (WorkerCategoryBO category : categories) {
                Long categoryId=category.getCategoryId();
                categoryIds.add(categoryId.intValue());
            }
        }
        workerDTO.setCategoryIds(categoryIds);
        workerDTO.setAreaIds(areaIds);
        return workerDTO;
    }
}
